from pyrem_strs._base_indexed import *
from pyrem_strs.config import _SLOTS_VALID_IN_UNICODE_DERIVED

def indexed_str(something):
    if isinstance(something, IndexedStr):
        return IndexedStr(something, something.index)
    if isinstance(something, unicode):
        return IndexedStr(something, 0)
    if isinstance(something, IndexedStr):
        return something
    raise TypeError

class IndexedStr(unicode): # immutable
    if _SLOTS_VALID_IN_UNICODE_DERIVED: __slots__ = [ '__index' ]
    
    def __new__(cls, s, index):
        assert isinstance(s, unicode)
        self = unicode.__new__(cls, s)
        self.__index = index
        return self
    
    @staticmethod
    def new_from_str_and_index(s, index):
        return IndexedStr(s, index)
    
    def __getindex(self): return self.__index
    index = property(__getindex, None, None)
    
    def __repr__(self):
        return "IndexedStr(%s,%s)" % ( repr(unicode(self)), repr(self.__index) )
    
    def __getitem__(self, pos):
        self_str = unicode(self)
        curLength = len(self_str)
        if pos < 0:
            pos = curLength + pos
        if not (0 <= pos < curLength):
            raise IndexError, "IndexedStr index out of range"
        
        return IndexedStr(self_str[pos : pos + 1], self.__index + pos)

    def __getslice__(self, beg, end):
        self_str = unicode(self)
        curLength = len(self_str)
        if beg < 0:
            beg = curLength + beg
            if beg < 0: raise IndexError, "IndexedStr index out of range"
        if end < 0:
            end = curLength + end
            if end < 0: raise IndexError, "IndexedStr index out of range"
        if beg > end:
            end = beg
        
        return IndexedStr(self_str[beg:end], self.__index + beg)
    
    def __add__(self, right):
        raise IndexedStrAttributeError("__add__ is not supported in IndexedStr")
    
    def __mul__(self, right):
        raise IndexedStrAttributeError("__mul__ is not supported in IndexedStr")
    
    def __rmul__(self, left):
        raise IndexedStrAttributeError("__rmul__ is not supported in IndexedStr")
    
    def expandtabs(self):
        raise IndexedStrAttributeError("expandtabs is not supported in IndexedStr")
    
    def lower(self):
        raise IndexedStrAttributeError("lower is not supported in IndexedStr")
    
    def upper(self):
        raise IndexedStrAttributeError("upper is not supported in IndexedStr")
    
    def swapcase(self):
        raise IndexedStrAttributeError("swapcase is not supported in IndexedStr")
    
    def strip(self):
        raise IndexedStrAttributeError("strip is not supported in IndexedStr")
    
    def lstrip(self):
        raise IndexedStrAttributeError("lstrip is not supported in IndexedStr")
    
    def rstrip(self):
        raise IndexedStrAttributeError("rstrip is not supported in IndexedStr")

    def ljust(self):
        raise IndexedStrAttributeError("ljust is not supported in IndexedStr")
    
    def rjust(self):
        raise IndexedStrAttributeError("rjust is not supported in IndexedStr")
    
    def partition(self, sep):
        raise IndexedStrAttributeError("partition is not supported in IndexedStr")

    def rpartition(self, sep):
        raise IndexedStrAttributeError("rpartition is not supported in IndexedStr")

    def title(self):
        raise IndexedStrAttributeError("title is not supported in IndexedStr")
    
    def translate(self):
        raise IndexedStrAttributeError("translate is not supported in IndexedStr")
    
    def splitlines(self, keepends=False):
        raise IndexedStrAttributeError("splitlines is not supported in IndexedStr")

    
